#include "pin_map_elite.h"
#include "stm32f10x.h"
#include "string.h"
#include "stdio.h"


void RCC_Configuration(void);
void GPIO_Configuration(void);
void DMA_Configuration(void);
void USART_Configuration(u16 baud);
void delay_nms(u16 time);
//发送字符
u8 USART_SendChar(USART_TypeDef* USARTx, u8 ucChar);
// 发送字符串
void USART_SendString(USART_TypeDef* USARTx, u8* pucStr);


uint8_t SrcBuf[14] = "Hello Qlu IOT";
uint8_t CmdBuf[14];
int main() {
    u8 flag = 1;
    RCC_Configuration();
    GPIO_Configuration();
    DMA_Configuration();
    USART_Configuration(9600);

    USART_ClearFlag(USART1, USART_FLAG_TC);
    USART_DMACmd(USART1, USART_DMAReq_Rx, ENABLE);
    DMA_Cmd(DMA1_Channel5, ENABLE);

    printf("Hello\r\n");

    while (flag) {
        if (strstr((char*)CmdBuf, "LED")) {
            printf("%s\r\n", CmdBuf);
            flag = 0;
        }
    }
    while (1) {
        GPIOE->ODR ^= LED1_Pin;
        delay_nms(200);
    }
}

void RCC_Configuration() {
    SystemInit();

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOE, ENABLE);
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);
    RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);
}

void GPIO_Configuration() {
    GPIO_InitTypeDef GPIO_InitStructure;

    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;  // 配置管脚PA10/USART1_RX
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
    GPIO_Init(GPIOA, &GPIO_InitStructure);

    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;  // 配置管脚PA9/USART1_TX
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOA, &GPIO_InitStructure);

    GPIO_InitStructure.GPIO_Pin = LED1_Pin;  // LED1
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOE, &GPIO_InitStructure);

    GPIO_SetBits(GPIOE, LED1_Pin);
}

void DMA_Configuration() {
    DMA_InitTypeDef DMA_InitStructure;


    // Channel5 RX
    DMA_DeInit(DMA1_Channel5);  // 重置DMA的寄存器的值,配置为缺省值
    DMA_InitStructure.DMA_PeripheralBaseAddr =
        (u32)&USART1->DR;  // 设置DMA外设基地址,即源数据存储区的首地址
    DMA_InitStructure.DMA_MemoryBaseAddr = (u32)CmdBuf;  // 定义内存基地址
    DMA_InitStructure.DMA_DIR =
        DMA_DIR_PeripheralSRC;  // 设置数据传输方向, 内存到外设
    DMA_InitStructure.DMA_BufferSize = 14;  // 指定DMA通道DAM缓存大小
    DMA_InitStructure.DMA_PeripheralInc =
        DMA_PeripheralInc_Disable;  // 设置外设数据指针调整模数,地址指针自动增加
    DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;  // 设置内存地址递增
    DMA_InitStructure.DMA_PeripheralDataSize =
        DMA_PeripheralDataSize_Byte;  // 定义外设和内存的宽度
    DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
    DMA_InitStructure.DMA_Mode =
        CAN_Mode_Normal;  // 设定DMA为工作模式为正常模式,
                          // 即按照指定的缓存大小传输,不再进行循环
    DMA_InitStructure.DMA_Priority =
        DMA_Priority_High;  // 设定DMA选定的通道的软件优先级
    DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;  // 开启存储器到存储器的模式
    DMA_Init(DMA1_Channel5, &DMA_InitStructure);
}
void USART_Configuration(u16 baud) {
    USART_InitTypeDef USART_InitStructure;

    /**
     * baud 的波特率
     * 8个数据位
     * 一位停止位
     * 无校验位
     */

    USART_InitStructure.USART_BaudRate = baud;
    USART_InitStructure.USART_WordLength = USART_WordLength_8b;
    USART_InitStructure.USART_StopBits = USART_StopBits_1;
    USART_InitStructure.USART_Parity = USART_Parity_No;
    USART_InitStructure.USART_HardwareFlowControl =
        USART_HardwareFlowControl_None;
    USART_InitStructure.USART_Mode = USART_Mode_Tx | USART_Mode_Rx;
    USART_Init(USART1, &USART_InitStructure);  //初始化串口

    USART_Cmd(USART1, ENABLE);  //启动USART
}


//发送字符
u8 USART_SendChar(USART_TypeDef* USARTx, u8 ucChar) {
	while (!USART_GetFlagStatus(USARTx, USART_FLAG_TXE));
	USART_SendData(USARTx, ucChar);
	return ucChar;
}
// 发送字符串
void USART_SendString(USART_TypeDef* USARTx, u8* pucStr) {
	while (*pucStr != '\0')
		USART_SendData(USARTx, *pucStr++);	
}

int fputc(int ch, FILE *f) {
	return (USART_SendChar(USART1, (u8)ch));
}

void delay_nms(u16 time)//延时子程序
{  u16 i=0;  
   while(time--)
   {  i=12000;  //自己定义
      while(i--) ; 
   }
}
